🎖️GitЯра🎖️
Node / meshtastic / Meshtastic-Android / files / core / data / src / commonMain / kotlin / org / meshtastic / core / data / manager / CommandSenderImpl.kt
Displaying Raw • Download
core/data/src/commonMain/kotlin/org/meshtastic/core/data/manager/CommandSenderImpl.kt 2d20cd8a4708e2ef66e98d5259f3a97ec93f240a (2d20cd8a) Text, 20.37 KB
T8b949e/*
* Copyright (c) 2026 Meshtastic LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
Tff7b72package T7ee787org.meshtastic.core.data.manager
Tff7b72import T7ee787co.touchlab.kermit.Logger
Tff7b72import T7ee787kotlinx.atomicfu.atomic
Tff7b72import T7ee787kotlinx.coroutines.CoroutineScope
Tff7b72import T7ee787kotlinx.coroutines.flow.MutableStateFlow
Tff7b72import T7ee787kotlinx.coroutines.flow.launchIn
Tff7b72import T7ee787kotlinx.coroutines.flow.onEach
Tff7b72import T7ee787okio.ByteString
Tff7b72import T7ee787okio.ByteString.Companion.toByteString
Tff7b72import T7ee787org.koin.core.annotation.Named
Tff7b72import T7ee787org.koin.core.annotation.Single
Tff7b72import T7ee787org.meshtastic.core.common.util.nowMillis
Tff7b72import T7ee787org.meshtastic.core.model.DataPacket
Tff7b72import T7ee787org.meshtastic.core.model.MessageStatus
Tff7b72import T7ee787org.meshtastic.core.model.NodeAddress
Tff7b72import T7ee787org.meshtastic.core.model.Position
Tff7b72import T7ee787org.meshtastic.core.model.TelemetryType
Tff7b72import T7ee787org.meshtastic.core.model.util.isWithinSizeLimit
Tff7b72import T7ee787org.meshtastic.core.repository.CommandSender
Tff7b72import T7ee787org.meshtastic.core.repository.NeighborInfoHandler
Tff7b72import T7ee787org.meshtastic.core.repository.NodeManager
Tff7b72import T7ee787org.meshtastic.core.repository.PacketHandler
Tff7b72import T7ee787org.meshtastic.core.repository.RadioConfigRepository
Tff7b72import T7ee787org.meshtastic.core.repository.SessionManager
Tff7b72import T7ee787org.meshtastic.core.repository.TracerouteHandler
Tff7b72import T7ee787org.meshtastic.proto.AdminMessage
Tff7b72import T7ee787org.meshtastic.proto.AirQualityMetrics
Tff7b72import T7ee787org.meshtastic.proto.ChannelSet
Tff7b72import T7ee787org.meshtastic.proto.Constants
Tff7b72import T7ee787org.meshtastic.proto.Data
Tff7b72import T7ee787org.meshtastic.proto.DeviceMetrics
Tff7b72import T7ee787org.meshtastic.proto.EnvironmentMetrics
Tff7b72import T7ee787org.meshtastic.proto.HostMetrics
Tff7b72import T7ee787org.meshtastic.proto.LocalConfig
Tff7b72import T7ee787org.meshtastic.proto.LocalStats
Tff7b72import T7ee787org.meshtastic.proto.LockdownAuth
Tff7b72import T7ee787org.meshtastic.proto.MeshPacket
Tff7b72import T7ee787org.meshtastic.proto.Neighbor
Tff7b72import T7ee787org.meshtastic.proto.NeighborInfo
Tff7b72import T7ee787org.meshtastic.proto.Paxcount
Tff7b72import T7ee787org.meshtastic.proto.PortNum
Tff7b72import T7ee787org.meshtastic.proto.PowerMetrics
Tff7b72import T7ee787org.meshtastic.proto.Telemetry
Tff7b72import T7ee787org.meshtastic.proto.ToRadio
Tff7b72import T7ee787kotlin.math.absoluteValue
Tff7b72import T7ee787kotlin.random.Random
Tff7b72import T7ee787kotlin.time.Duration.Companion.hours
Tff7b72import T7ee787org.meshtastic.proto.Position Tff7b72as Te6edf3ProtoPosition
Tf0883e@SuppressTb4b4b4(Ta5d6ff"Ta5d6ffTooManyFunctionsTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffCyclomaticComplexMethodTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffLongParameterListTa5d6ff"Tb4b4b4)
Tf0883e@Single
Tff7b72class T56d364CommandSenderImplTb4b4b4(
Tff7b72private Tff7b72val Te6edf3packetHandlerTb4b4b4: Te6edf3PacketHandlerTb4b4b4,
Tff7b72private Tff7b72val Te6edf3nodeManagerTb4b4b4: Te6edf3NodeManagerTb4b4b4,
Tff7b72private Tff7b72val Te6edf3radioConfigRepositoryTb4b4b4: Te6edf3RadioConfigRepositoryTb4b4b4,
Tff7b72private Tff7b72val Te6edf3tracerouteHandlerTb4b4b4: Te6edf3TracerouteHandlerTb4b4b4,
Tff7b72private Tff7b72val Te6edf3neighborInfoHandlerTb4b4b4: Te6edf3NeighborInfoHandlerTb4b4b4,
Tff7b72private Tff7b72val Te6edf3sessionManagerTb4b4b4: Te6edf3SessionManagerTb4b4b4,
Tf0883e@NamedTb4b4b4(Ta5d6ff"Ta5d6ffServiceScopeTa5d6ff"Tb4b4b4) Tff7b72private Tff7b72val Te6edf3scopeTb4b4b4: Te6edf3CoroutineScopeTb4b4b4,
Tb4b4b4) Tb4b4b4: Te6edf3CommandSender Tb4b4b4{
Tff7b72private Tff7b72val Te6edf3currentPacketId Tff7b72= Te6edf3atomicTb4b4b4(Te6edf3RandomTb4b4b4(Te6edf3nowMillisTb4b4b4)Tb4b4b4.Te6edf3nextLongTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3absoluteValueTb4b4b4)
Tff7b72private Tff7b72val Te6edf3localConfig Tff7b72= Te6edf3MutableStateFlowTb4b4b4(Te6edf3LocalConfigTb4b4b4(Tb4b4b4)Tb4b4b4)
Tff7b72private Tff7b72val Te6edf3channelSet Tff7b72= Te6edf3MutableStateFlowTb4b4b4(Te6edf3ChannelSetTb4b4b4(Tb4b4b4)Tb4b4b4)
Tff7b72init Tb4b4b4{
Te6edf3radioConfigRepositoryTb4b4b4.Te6edf3localConfigFlowTb4b4b4.Te6edf3onEach Tb4b4b4{ Te6edf3localConfigTb4b4b4.Te6edf3value Tff7b72= Tffa657it Tb4b4b4}Tb4b4b4.Te6edf3launchInTb4b4b4(Te6edf3scopeTb4b4b4)
Te6edf3radioConfigRepositoryTb4b4b4.Te6edf3channelSetFlowTb4b4b4.Te6edf3onEach Tb4b4b4{ Te6edf3channelSetTb4b4b4.Te6edf3value Tff7b72= Tffa657it Tb4b4b4}Tb4b4b4.Te6edf3launchInTb4b4b4(Te6edf3scopeTb4b4b4)
Tb4b4b4}
Tff7b72override Tff7b72fun Td2a8ffgetCachedLocalConfigTb4b4b4(Tb4b4b4)Tb4b4b4: Te6edf3LocalConfig Tff7b72= Te6edf3localConfigTb4b4b4.Te6edf3value
Tff7b72override Tff7b72fun Td2a8ffgetCachedChannelSetTb4b4b4(Tb4b4b4)Tb4b4b4: Te6edf3ChannelSet Tff7b72= Te6edf3channelSetTb4b4b4.Te6edf3value
Tff7b72override Tff7b72fun Td2a8ffgetCurrentPacketIdTb4b4b4(Tb4b4b4)Tb4b4b4: Tffa657Long Tff7b72= Te6edf3currentPacketIdTb4b4b4.Te6edf3value
Tff7b72override Tff7b72fun Td2a8ffgeneratePacketIdTb4b4b4(Tb4b4b4)Tb4b4b4: Tffa657Int Tb4b4b4{
Tff7b72val Te6edf3numPacketIds Tff7b72= Tb4b4b4(Tb4b4b4(T79c0ff1L Te6edf3shl Te6edf3PACKET_ID_SHIFT_BITSTb4b4b4) Tff7b72- T79c0ff1Tb4b4b4)
Tff7b72val Te6edf3next Tff7b72= Te6edf3currentPacketIdTb4b4b4.Te6edf3incrementAndGetTb4b4b4(Tb4b4b4) Te6edf3and Te6edf3PACKET_ID_MASK
Tff7b72return Tb4b4b4(Tb4b4b4(Te6edf3next Tff7b72% Te6edf3numPacketIdsTb4b4b4) Tff7b72+ T79c0ff1LTb4b4b4)Tb4b4b4.Te6edf3toIntTb4b4b4(Tb4b4b4)
Tb4b4b4}
Tff7b72private Tff7b72fun Td2a8ffcomputeHopLimitTb4b4b4(Tb4b4b4)Tb4b4b4: Tffa657Int Tff7b72= Tb4b4b4(Te6edf3localConfigTb4b4b4.Te6edf3valueTb4b4b4.Te6edf3loraTff7b72?.Te6edf3hop_limit Tff7b72?: T79c0ff0Tb4b4b4)Tb4b4b4.Te6edf3takeIf Tb4b4b4{ Tffa657it Tff7b72> T79c0ff0 Tb4b4b4} Tff7b72?: Te6edf3DEFAULT_HOP_LIMIT
T8b949e/**
* Resolves the correct channel index for sending a packet to [toNum].
*
* PKI encryption ([NodeAddress.PKC_CHANNEL_INDEX]) is only used for **admin** packets, where end-to-end encryption
* is appropriate. Protocol-level requests (traceroute, telemetry, position, nodeinfo, neighborinfo) must NOT use
* PKI because relay nodes need to read and/or modify the inner payload (e.g. traceroute appends each hop's node
* number). These requests fall back to the node's heard-on channel.
*/
Tff7b72private Tff7b72fun Td2a8ffgetAdminChannelIndexTb4b4b4(Te6edf3toNumTb4b4b4: Tffa657IntTb4b4b4)Tb4b4b4: Tffa657Int Tb4b4b4{
Tff7b72val Te6edf3myNum Tff7b72= Te6edf3nodeManagerTb4b4b4.Te6edf3myNodeNumTb4b4b4.Te6edf3value Tff7b72?: Tff7b72return T79c0ff0
Tff7b72val Te6edf3myNode Tff7b72= Te6edf3nodeManagerTb4b4b4.Te6edf3nodeDBbyNodeNumTff7b72[Te6edf3myNumTff7b72]
Tff7b72val Te6edf3destNode Tff7b72= Te6edf3nodeManagerTb4b4b4.Te6edf3nodeDBbyNodeNumTff7b72[Te6edf3toNumTff7b72]
Tff7b72return Tff7b72when Tb4b4b4{
Te6edf3myNum Tff7b72=Tff7b72= Te6edf3toNum Tff7b72-Tff7b72> T79c0ff0
Te6edf3myNodeTff7b72?.Te6edf3hasPKC Tff7b72=Tff7b72= Tff7b72true Tff7b72&Tff7b72& Te6edf3destNodeTff7b72?.Te6edf3hasPKC Tff7b72=Tff7b72= Tff7b72true Tff7b72-Tff7b72> Te6edf3NodeAddressTb4b4b4.Te6edf3PKC_CHANNEL_INDEX
Tff7b72else Tff7b72-Tff7b72>
Te6edf3channelSetTb4b4b4.Te6edf3valueTb4b4b4.Te6edf3settings
Tb4b4b4.Te6edf3indexOfFirst Tb4b4b4{ Tffa657itTb4b4b4.Te6edf3nameTb4b4b4.Te6edf3equalsTb4b4b4(Te6edf3ADMIN_CHANNEL_NAMETb4b4b4, Te6edf3ignoreCase Tff7b72= Tff7b72trueTb4b4b4) Tb4b4b4}
Tb4b4b4.Te6edf3coerceAtLeastTb4b4b4(T79c0ff0Tb4b4b4)
Tb4b4b4}
Tb4b4b4}
T8b949e/**
* Returns the heard-on channel for a non-admin request to [toNum]. Does NOT use PKI — protocol-level requests need
* clear inner payloads.
*/
Tff7b72private Tff7b72fun Td2a8ffgetChannelIndexTb4b4b4(Te6edf3toNumTb4b4b4: Tffa657IntTb4b4b4)Tb4b4b4: Tffa657Int Tff7b72= Te6edf3nodeManagerTb4b4b4.Te6edf3nodeDBbyNodeNumTff7b72[Te6edf3toNumTff7b72]Tff7b72?.Te6edf3channel Tff7b72?: T79c0ff0
Tff7b72override Tff7b72suspend Tff7b72fun Td2a8ffsendDataTb4b4b4(Te6edf3pTb4b4b4: Te6edf3DataPacketTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3pTb4b4b4.Te6edf3id Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Te6edf3pTb4b4b4.Te6edf3id Tff7b72= Te6edf3generatePacketIdTb4b4b4(Tb4b4b4)
Tff7b72val Te6edf3bytes Tff7b72= Te6edf3pTb4b4b4.Te6edf3bytes Tff7b72?: Te6edf3ByteStringTb4b4b4.Te6edf3EMPTY
Te6edf3requireTb4b4b4(Te6edf3pTb4b4b4.Te6edf3dataType Tff7b72!Tff7b72= T79c0ff0Tb4b4b4) Tb4b4b4{ Ta5d6ff"Ta5d6ffPort numbers must be non-zero!Ta5d6ff" Tb4b4b4}
T8b949e// Use Wire extension for accurate size validation
Tff7b72val Te6edf3data Tff7b72=
Te6edf3DataTb4b4b4(
Te6edf3portnum Tff7b72= Te6edf3PortNumTb4b4b4.Te6edf3fromValueTb4b4b4(Te6edf3pTb4b4b4.Te6edf3dataTypeTb4b4b4) Tff7b72?: Te6edf3PortNumTb4b4b4.Te6edf3UNKNOWN_APPTb4b4b4,
Te6edf3payload Tff7b72= Te6edf3bytesTb4b4b4,
Te6edf3reply_id Tff7b72= Te6edf3pTb4b4b4.Te6edf3replyId Tff7b72?: T79c0ff0Tb4b4b4,
Te6edf3emoji Tff7b72= Te6edf3pTb4b4b4.Te6edf3emojiTb4b4b4,
Tb4b4b4)
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3DataTb4b4b4.Te6edf3ADAPTERTb4b4b4.Te6edf3isWithinSizeLimitTb4b4b4(Te6edf3dataTb4b4b4, Te6edf3ConstantsTb4b4b4.Te6edf3DATA_PAYLOAD_LENTb4b4b4.Te6edf3valueTb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3actualSize Tff7b72= Te6edf3DataTb4b4b4.Te6edf3ADAPTERTb4b4b4.Te6edf3encodedSizeTb4b4b4(Te6edf3dataTb4b4b4)
Te6edf3pTb4b4b4.Te6edf3status Tff7b72= Te6edf3MessageStatusTb4b4b4.Te6edf3ERROR
Te6edf3errorTb4b4b4(Ta5d6ff"Ta5d6ffMessage too long: Tffd700$Te6edf3actualSizeTa5d6ff bytesTa5d6ff"Tb4b4b4)
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3pTb4b4b4.Te6edf3status Tff7b72= Te6edf3MessageStatusTb4b4b4.Te6edf3QUEUED
Tb4b4b4}
Te6edf3sendNowTb4b4b4(Te6edf3pTb4b4b4)
Tb4b4b4}
Tff7b72private Tff7b72suspend Tff7b72fun Td2a8ffsendNowTb4b4b4(Te6edf3pTb4b4b4: Te6edf3DataPacketTb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3meshPacket Tff7b72=
Te6edf3buildMeshPacketTb4b4b4(
Te6edf3to Tff7b72= Te6edf3resolveNodeNumTb4b4b4(Te6edf3NodeAddressTb4b4b4.Te6edf3fromStringTb4b4b4(Te6edf3pTb4b4b4.Te6edf3toTb4b4b4)Tb4b4b4)Tb4b4b4,
Te6edf3id Tff7b72= Te6edf3pTb4b4b4.Te6edf3idTb4b4b4,
Te6edf3wantAck Tff7b72= Te6edf3pTb4b4b4.Te6edf3wantAckTb4b4b4,
Te6edf3hopLimit Tff7b72= Tff7b72if Tb4b4b4(Te6edf3pTb4b4b4.Te6edf3hopLimit Tff7b72> T79c0ff0Tb4b4b4) Te6edf3pTb4b4b4.Te6edf3hopLimit Tff7b72else Te6edf3computeHopLimitTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3channel Tff7b72= Te6edf3pTb4b4b4.Te6edf3channelTb4b4b4,
Te6edf3decoded Tff7b72=
Te6edf3DataTb4b4b4(
Te6edf3portnum Tff7b72= Te6edf3PortNumTb4b4b4.Te6edf3fromValueTb4b4b4(Te6edf3pTb4b4b4.Te6edf3dataTypeTb4b4b4) Tff7b72?: Te6edf3PortNumTb4b4b4.Te6edf3UNKNOWN_APPTb4b4b4,
Te6edf3payload Tff7b72= Te6edf3pTb4b4b4.Te6edf3bytes Tff7b72?: Te6edf3ByteStringTb4b4b4.Te6edf3EMPTYTb4b4b4,
Te6edf3reply_id Tff7b72= Te6edf3pTb4b4b4.Te6edf3replyId Tff7b72?: T79c0ff0Tb4b4b4,
Te6edf3emoji Tff7b72= Te6edf3pTb4b4b4.Te6edf3emojiTb4b4b4,
Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Te6edf3pTb4b4b4.Te6edf3time Tff7b72= Te6edf3nowMillis
Te6edf3packetHandlerTb4b4b4.Te6edf3sendToRadioTb4b4b4(Te6edf3meshPacketTb4b4b4)
Tb4b4b4}
Tff7b72override Tff7b72suspend Tff7b72fun Td2a8ffsendAdminTb4b4b4(Te6edf3destNumTb4b4b4: Tffa657IntTb4b4b4, Te6edf3requestIdTb4b4b4: Tffa657IntTb4b4b4, Te6edf3wantResponseTb4b4b4: Tffa657BooleanTb4b4b4, Te6edf3initFnTb4b4b4: Tb4b4b4(Tb4b4b4) Tff7b72-Tff7b72> Te6edf3AdminMessageTb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3adminMsg Tff7b72= Te6edf3initFnTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3copyTb4b4b4(Te6edf3session_passkey Tff7b72= Te6edf3sessionManagerTb4b4b4.Te6edf3getPasskeyTb4b4b4(Te6edf3destNumTb4b4b4)Tb4b4b4)
Tff7b72val Te6edf3packet Tff7b72=
Te6edf3buildAdminPacketTb4b4b4(Te6edf3to Tff7b72= Te6edf3destNumTb4b4b4, Te6edf3id Tff7b72= Te6edf3requestIdTb4b4b4, Te6edf3wantResponse Tff7b72= Te6edf3wantResponseTb4b4b4, Te6edf3adminMessage Tff7b72= Te6edf3adminMsgTb4b4b4)
Te6edf3packetHandlerTb4b4b4.Te6edf3sendToRadioTb4b4b4(Te6edf3packetTb4b4b4)
Tb4b4b4}
Tff7b72override Tff7b72fun Td2a8ffsendAdminImmediateTb4b4b4(Te6edf3destNumTb4b4b4: Tffa657IntTb4b4b4, Te6edf3initFnTb4b4b4: Tb4b4b4(Tb4b4b4) Tff7b72-Tff7b72> Te6edf3AdminMessageTb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3adminMsg Tff7b72= Te6edf3initFnTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3copyTb4b4b4(Te6edf3session_passkey Tff7b72= Te6edf3sessionManagerTb4b4b4.Te6edf3getPasskeyTb4b4b4(Te6edf3destNumTb4b4b4)Tb4b4b4)
Tff7b72val Te6edf3packet Tff7b72= Te6edf3buildAdminPacketTb4b4b4(Te6edf3to Tff7b72= Te6edf3destNumTb4b4b4, Te6edf3adminMessage Tff7b72= Te6edf3adminMsgTb4b4b4)
Te6edf3packetHandlerTb4b4b4.Te6edf3sendToRadioTb4b4b4(Te6edf3ToRadioTb4b4b4(Te6edf3packet Tff7b72= Te6edf3packetTb4b4b4)Tb4b4b4)
Tb4b4b4}
Tff7b72override Tff7b72suspend Tff7b72fun Td2a8ffsendAdminAwaitTb4b4b4(
Te6edf3destNumTb4b4b4: Tffa657IntTb4b4b4,
Te6edf3requestIdTb4b4b4: Tffa657IntTb4b4b4,
Te6edf3wantResponseTb4b4b4: Tffa657BooleanTb4b4b4,
Te6edf3initFnTb4b4b4: Tb4b4b4(Tb4b4b4) Tff7b72-Tff7b72> Te6edf3AdminMessageTb4b4b4,
Tb4b4b4)Tb4b4b4: Tffa657Boolean Tb4b4b4{
Tff7b72val Te6edf3adminMsg Tff7b72= Te6edf3initFnTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3copyTb4b4b4(Te6edf3session_passkey Tff7b72= Te6edf3sessionManagerTb4b4b4.Te6edf3getPasskeyTb4b4b4(Te6edf3destNumTb4b4b4)Tb4b4b4)
Tff7b72val Te6edf3packet Tff7b72=
Te6edf3buildAdminPacketTb4b4b4(Te6edf3to Tff7b72= Te6edf3destNumTb4b4b4, Te6edf3id Tff7b72= Te6edf3requestIdTb4b4b4, Te6edf3wantResponse Tff7b72= Te6edf3wantResponseTb4b4b4, Te6edf3adminMessage Tff7b72= Te6edf3adminMsgTb4b4b4)
Tff7b72return Te6edf3packetHandlerTb4b4b4.Te6edf3sendToRadioAndAwaitTb4b4b4(Te6edf3packetTb4b4b4)
Tb4b4b4}
Tff7b72override Tff7b72suspend Tff7b72fun Td2a8ffsendPositionTb4b4b4(Te6edf3posTb4b4b4: Te6edf3ProtoPositionTb4b4b4, Te6edf3destNumTb4b4b4: Tffa657Int?Tb4b4b4, Te6edf3wantResponseTb4b4b4: Tffa657BooleanTb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3myNum Tff7b72= Te6edf3nodeManagerTb4b4b4.Te6edf3myNodeNumTb4b4b4.Te6edf3value Tff7b72?: Tff7b72return
Tff7b72val Te6edf3idNum Tff7b72= Te6edf3destNum Tff7b72?: Te6edf3myNum
Te6edf3LoggerTb4b4b4.Te6edf3d Tb4b4b4{ Ta5d6ff"Ta5d6ffSending our position/time to=Tffd700$Te6edf3idNumTa5d6ff Tffd700$Te6edf3posTa5d6ff" Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3localConfigTb4b4b4.Te6edf3valueTb4b4b4.Te6edf3positionTff7b72?.Te6edf3fixed_position Tff7b72!Tff7b72= Tff7b72trueTb4b4b4) Tb4b4b4{
Te6edf3nodeManagerTb4b4b4.Te6edf3handleReceivedPositionTb4b4b4(Te6edf3myNumTb4b4b4, Te6edf3myNumTb4b4b4, Te6edf3posTb4b4b4, Te6edf3nowMillisTb4b4b4)
Tb4b4b4}
Te6edf3packetHandlerTb4b4b4.Te6edf3sendToRadioTb4b4b4(
Te6edf3buildMeshPacketTb4b4b4(
Te6edf3to Tff7b72= Te6edf3idNumTb4b4b4,
Te6edf3channel Tff7b72= Tff7b72if Tb4b4b4(Te6edf3destNum Tff7b72=Tff7b72= Tff7b72nullTb4b4b4) T79c0ff0 Tff7b72else Te6edf3getChannelIndexTb4b4b4(Te6edf3destNumTb4b4b4)Tb4b4b4,
Te6edf3priority Tff7b72= Te6edf3MeshPacketTb4b4b4.Te6edf3PriorityTb4b4b4.Te6edf3BACKGROUNDTb4b4b4,
Te6edf3decoded Tff7b72=
Te6edf3DataTb4b4b4(
Te6edf3portnum Tff7b72= Te6edf3PortNumTb4b4b4.Te6edf3POSITION_APPTb4b4b4,
Te6edf3payload Tff7b72= Te6edf3posTb4b4b4.Te6edf3encodeTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toByteStringTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3want_response Tff7b72= Te6edf3wantResponseTb4b4b4,
Tb4b4b4)Tb4b4b4,
Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Tb4b4b4}
Tff7b72override Tff7b72suspend Tff7b72fun Td2a8ffrequestPositionTb4b4b4(Te6edf3destNumTb4b4b4: Tffa657IntTb4b4b4, Te6edf3currentPositionTb4b4b4: Te6edf3PositionTb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3meshPosition Tff7b72=
Te6edf3ProtoPositionTb4b4b4(
Te6edf3latitude_i Tff7b72= Te6edf3PositionTb4b4b4.Te6edf3degITb4b4b4(Te6edf3currentPositionTb4b4b4.Te6edf3latitudeTb4b4b4)Tb4b4b4,
Te6edf3longitude_i Tff7b72= Te6edf3PositionTb4b4b4.Te6edf3degITb4b4b4(Te6edf3currentPositionTb4b4b4.Te6edf3longitudeTb4b4b4)Tb4b4b4,
Te6edf3altitude Tff7b72= Te6edf3currentPositionTb4b4b4.Te6edf3altitudeTb4b4b4,
Te6edf3time Tff7b72= Tb4b4b4(Te6edf3nowMillis Tff7b72/ T79c0ff1T79c0ff0T79c0ff0T79c0ff0LTb4b4b4)Tb4b4b4.Te6edf3toIntTb4b4b4(Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Te6edf3packetHandlerTb4b4b4.Te6edf3sendToRadioTb4b4b4(
Te6edf3buildMeshPacketTb4b4b4(
Te6edf3to Tff7b72= Te6edf3destNumTb4b4b4,
Te6edf3channel Tff7b72= Te6edf3getChannelIndexTb4b4b4(Te6edf3destNumTb4b4b4)Tb4b4b4,
Te6edf3priority Tff7b72= Te6edf3MeshPacketTb4b4b4.Te6edf3PriorityTb4b4b4.Te6edf3BACKGROUNDTb4b4b4,
Te6edf3decoded Tff7b72=
Te6edf3DataTb4b4b4(
Te6edf3portnum Tff7b72= Te6edf3PortNumTb4b4b4.Te6edf3POSITION_APPTb4b4b4,
Te6edf3payload Tff7b72= Te6edf3meshPositionTb4b4b4.Te6edf3encodeTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toByteStringTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3want_response Tff7b72= Tff7b72trueTb4b4b4,
Tb4b4b4)Tb4b4b4,
Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Tb4b4b4}
Tff7b72override Tff7b72suspend Tff7b72fun Td2a8ffsetFixedPositionTb4b4b4(Te6edf3destNumTb4b4b4: Tffa657IntTb4b4b4, Te6edf3posTb4b4b4: Te6edf3PositionTb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3meshPos Tff7b72=
Te6edf3ProtoPositionTb4b4b4(
Te6edf3latitude_i Tff7b72= Te6edf3PositionTb4b4b4.Te6edf3degITb4b4b4(Te6edf3posTb4b4b4.Te6edf3latitudeTb4b4b4)Tb4b4b4,
Te6edf3longitude_i Tff7b72= Te6edf3PositionTb4b4b4.Te6edf3degITb4b4b4(Te6edf3posTb4b4b4.Te6edf3longitudeTb4b4b4)Tb4b4b4,
Te6edf3altitude Tff7b72= Te6edf3posTb4b4b4.Te6edf3altitudeTb4b4b4,
Tb4b4b4)
Te6edf3sendAdminTb4b4b4(Te6edf3destNumTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3pos Tff7b72!Tff7b72= Te6edf3PositionTb4b4b4(T79c0ff0.0Tb4b4b4, T79c0ff0.0Tb4b4b4, T79c0ff0Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3AdminMessageTb4b4b4(Te6edf3set_fixed_position Tff7b72= Te6edf3meshPosTb4b4b4)
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3AdminMessageTb4b4b4(Te6edf3remove_fixed_position Tff7b72= Tff7b72trueTb4b4b4)
Tb4b4b4}
Tb4b4b4}
Te6edf3nodeManagerTb4b4b4.Te6edf3handleReceivedPositionTb4b4b4(Te6edf3destNumTb4b4b4, Te6edf3nodeManagerTb4b4b4.Te6edf3myNodeNumTb4b4b4.Te6edf3value Tff7b72?: T79c0ff0Tb4b4b4, Te6edf3meshPosTb4b4b4, Te6edf3nowMillisTb4b4b4)
Tb4b4b4}
Tff7b72override Tff7b72suspend Tff7b72fun Td2a8ffrequestUserInfoTb4b4b4(Te6edf3destNumTb4b4b4: Tffa657IntTb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3myNum Tff7b72= Te6edf3nodeManagerTb4b4b4.Te6edf3myNodeNumTb4b4b4.Te6edf3value Tff7b72?: Tff7b72return
Tff7b72val Te6edf3myNode Tff7b72= Te6edf3nodeManagerTb4b4b4.Te6edf3nodeDBbyNodeNumTff7b72[Te6edf3myNumTff7b72] Tff7b72?: Tff7b72return
Te6edf3packetHandlerTb4b4b4.Te6edf3sendToRadioTb4b4b4(
Te6edf3buildMeshPacketTb4b4b4(
Te6edf3to Tff7b72= Te6edf3destNumTb4b4b4,
Te6edf3channel Tff7b72= Te6edf3getChannelIndexTb4b4b4(Te6edf3destNumTb4b4b4)Tb4b4b4,
Te6edf3decoded Tff7b72=
Te6edf3DataTb4b4b4(
Te6edf3portnum Tff7b72= Te6edf3PortNumTb4b4b4.Te6edf3NODEINFO_APPTb4b4b4,
Te6edf3want_response Tff7b72= Tff7b72trueTb4b4b4,
Te6edf3payload Tff7b72= Te6edf3myNodeTb4b4b4.Te6edf3userTb4b4b4.Te6edf3encodeTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toByteStringTb4b4b4(Tb4b4b4)Tb4b4b4,
Tb4b4b4)Tb4b4b4,
Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Tb4b4b4}
Tff7b72override Tff7b72suspend Tff7b72fun Td2a8ffrequestTracerouteTb4b4b4(Te6edf3requestIdTb4b4b4: Tffa657IntTb4b4b4, Te6edf3destNumTb4b4b4: Tffa657IntTb4b4b4) Tb4b4b4{
Te6edf3tracerouteHandlerTb4b4b4.Te6edf3recordStartTimeTb4b4b4(Te6edf3requestIdTb4b4b4)
Te6edf3packetHandlerTb4b4b4.Te6edf3sendToRadioTb4b4b4(
Te6edf3buildMeshPacketTb4b4b4(
Te6edf3to Tff7b72= Te6edf3destNumTb4b4b4,
Te6edf3wantAck Tff7b72= Tff7b72trueTb4b4b4,
Te6edf3id Tff7b72= Te6edf3requestIdTb4b4b4,
Te6edf3channel Tff7b72= Te6edf3getChannelIndexTb4b4b4(Te6edf3destNumTb4b4b4)Tb4b4b4,
Te6edf3decoded Tff7b72= Te6edf3DataTb4b4b4(Te6edf3portnum Tff7b72= Te6edf3PortNumTb4b4b4.Te6edf3TRACEROUTE_APPTb4b4b4, Te6edf3want_response Tff7b72= Tff7b72trueTb4b4b4, Te6edf3dest Tff7b72= Te6edf3destNumTb4b4b4)Tb4b4b4,
Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Tb4b4b4}
Tff7b72override Tff7b72suspend Tff7b72fun Td2a8ffrequestTelemetryTb4b4b4(Te6edf3requestIdTb4b4b4: Tffa657IntTb4b4b4, Te6edf3destNumTb4b4b4: Tffa657IntTb4b4b4, Te6edf3typeValueTb4b4b4: Tffa657IntTb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3type Tff7b72= Te6edf3TelemetryTypeTb4b4b4.Te6edf3entriesTb4b4b4.Te6edf3getOrNullTb4b4b4(Te6edf3typeValueTb4b4b4) Tff7b72?: Te6edf3TelemetryTypeTb4b4b4.Te6edf3DEVICE
Tff7b72val Te6edf3portNumTb4b4b4: Te6edf3PortNum
Tff7b72val Te6edf3payloadBytesTb4b4b4: Te6edf3ByteString
Tff7b72if Tb4b4b4(Te6edf3type Tff7b72=Tff7b72= Te6edf3TelemetryTypeTb4b4b4.Te6edf3PAXTb4b4b4) Tb4b4b4{
Te6edf3portNum Tff7b72= Te6edf3PortNumTb4b4b4.Te6edf3PAXCOUNTER_APP
Te6edf3payloadBytes Tff7b72= Te6edf3PaxcountTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3encodeTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toByteStringTb4b4b4(Tb4b4b4)
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3portNum Tff7b72= Te6edf3PortNumTb4b4b4.Te6edf3TELEMETRY_APP
Te6edf3payloadBytes Tff7b72=
Te6edf3TelemetryTb4b4b4(
Te6edf3device_metrics Tff7b72= Tff7b72if Tb4b4b4(Te6edf3type Tff7b72=Tff7b72= Te6edf3TelemetryTypeTb4b4b4.Te6edf3DEVICETb4b4b4) Te6edf3DeviceMetricsTb4b4b4(Tb4b4b4) Tff7b72else Tff7b72nullTb4b4b4,
Te6edf3environment_metrics Tff7b72= Tff7b72if Tb4b4b4(Te6edf3type Tff7b72=Tff7b72= Te6edf3TelemetryTypeTb4b4b4.Te6edf3ENVIRONMENTTb4b4b4) Te6edf3EnvironmentMetricsTb4b4b4(Tb4b4b4) Tff7b72else Tff7b72nullTb4b4b4,
Te6edf3air_quality_metrics Tff7b72= Tff7b72if Tb4b4b4(Te6edf3type Tff7b72=Tff7b72= Te6edf3TelemetryTypeTb4b4b4.Te6edf3AIR_QUALITYTb4b4b4) Te6edf3AirQualityMetricsTb4b4b4(Tb4b4b4) Tff7b72else Tff7b72nullTb4b4b4,
Te6edf3power_metrics Tff7b72= Tff7b72if Tb4b4b4(Te6edf3type Tff7b72=Tff7b72= Te6edf3TelemetryTypeTb4b4b4.Te6edf3POWERTb4b4b4) Te6edf3PowerMetricsTb4b4b4(Tb4b4b4) Tff7b72else Tff7b72nullTb4b4b4,
Te6edf3local_stats Tff7b72= Tff7b72if Tb4b4b4(Te6edf3type Tff7b72=Tff7b72= Te6edf3TelemetryTypeTb4b4b4.Te6edf3LOCAL_STATSTb4b4b4) Te6edf3LocalStatsTb4b4b4(Tb4b4b4) Tff7b72else Tff7b72nullTb4b4b4,
Te6edf3host_metrics Tff7b72= Tff7b72if Tb4b4b4(Te6edf3type Tff7b72=Tff7b72= Te6edf3TelemetryTypeTb4b4b4.Te6edf3HOSTTb4b4b4) Te6edf3HostMetricsTb4b4b4(Tb4b4b4) Tff7b72else Tff7b72nullTb4b4b4,
Tb4b4b4)
Tb4b4b4.Te6edf3encodeTb4b4b4(Tb4b4b4)
Tb4b4b4.Te6edf3toByteStringTb4b4b4(Tb4b4b4)
Tb4b4b4}
Te6edf3packetHandlerTb4b4b4.Te6edf3sendToRadioTb4b4b4(
Te6edf3buildMeshPacketTb4b4b4(
Te6edf3to Tff7b72= Te6edf3destNumTb4b4b4,
Te6edf3id Tff7b72= Te6edf3requestIdTb4b4b4,
Te6edf3channel Tff7b72= Te6edf3getChannelIndexTb4b4b4(Te6edf3destNumTb4b4b4)Tb4b4b4,
Te6edf3decoded Tff7b72= Te6edf3DataTb4b4b4(Te6edf3portnum Tff7b72= Te6edf3portNumTb4b4b4, Te6edf3payload Tff7b72= Te6edf3payloadBytesTb4b4b4, Te6edf3want_response Tff7b72= Tff7b72trueTb4b4b4, Te6edf3dest Tff7b72= Te6edf3destNumTb4b4b4)Tb4b4b4,
Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Tb4b4b4}
Tff7b72override Tff7b72suspend Tff7b72fun Td2a8ffrequestNeighborInfoTb4b4b4(Te6edf3requestIdTb4b4b4: Tffa657IntTb4b4b4, Te6edf3destNumTb4b4b4: Tffa657IntTb4b4b4) Tb4b4b4{
Te6edf3neighborInfoHandlerTb4b4b4.Te6edf3recordStartTimeTb4b4b4(Te6edf3requestIdTb4b4b4)
Tff7b72val Te6edf3myNum Tff7b72= Te6edf3nodeManagerTb4b4b4.Te6edf3myNodeNumTb4b4b4.Te6edf3value Tff7b72?: T79c0ff0
Tff7b72if Tb4b4b4(Te6edf3destNum Tff7b72=Tff7b72= Te6edf3myNumTb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3neighborInfoToSend Tff7b72=
Te6edf3neighborInfoHandlerTb4b4b4.Te6edf3lastNeighborInfo
Tff7b72?: Te6edf3run Tb4b4b4{
Tff7b72val Te6edf3oneHour Tff7b72= T79c0ff1.Te6edf3hoursTb4b4b4.Te6edf3inWholeMinutesTb4b4b4.Te6edf3toIntTb4b4b4(Tb4b4b4)
Te6edf3LoggerTb4b4b4.Te6edf3d Tb4b4b4{ Ta5d6ff"Ta5d6ffNo stored neighbor info from connected radio, sending dummy dataTa5d6ff" Tb4b4b4}
Te6edf3NeighborInfoTb4b4b4(
Te6edf3node_id Tff7b72= Te6edf3myNumTb4b4b4,
Te6edf3last_sent_by_id Tff7b72= Te6edf3myNumTb4b4b4,
Te6edf3node_broadcast_interval_secs Tff7b72= Te6edf3oneHourTb4b4b4,
Te6edf3neighbors Tff7b72=
Te6edf3listOfTb4b4b4(
Te6edf3NeighborTb4b4b4(
Te6edf3node_id Tff7b72= T79c0ff0Tb4b4b4, T8b949e// Dummy node ID that can be intercepted
Te6edf3snr Tff7b72= T79c0ff0fTb4b4b4,
Te6edf3last_rx_time Tff7b72= Tb4b4b4(Te6edf3nowMillis Tff7b72/ T79c0ff1T79c0ff0T79c0ff0T79c0ff0LTb4b4b4)Tb4b4b4.Te6edf3toIntTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3node_broadcast_interval_secs Tff7b72= Te6edf3oneHourTb4b4b4,
Tb4b4b4)Tb4b4b4,
Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Tb4b4b4}
T8b949e// Send the neighbor info from our connected radio to ourselves (simulated)
Te6edf3packetHandlerTb4b4b4.Te6edf3sendToRadioTb4b4b4(
Te6edf3buildMeshPacketTb4b4b4(
Te6edf3to Tff7b72= Te6edf3destNumTb4b4b4,
Te6edf3wantAck Tff7b72= Tff7b72trueTb4b4b4,
Te6edf3id Tff7b72= Te6edf3requestIdTb4b4b4,
Te6edf3channel Tff7b72= Te6edf3getChannelIndexTb4b4b4(Te6edf3destNumTb4b4b4)Tb4b4b4,
Te6edf3decoded Tff7b72=
Te6edf3DataTb4b4b4(
Te6edf3portnum Tff7b72= Te6edf3PortNumTb4b4b4.Te6edf3NEIGHBORINFO_APPTb4b4b4,
Te6edf3payload Tff7b72= Te6edf3neighborInfoToSendTb4b4b4.Te6edf3encodeTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toByteStringTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3want_response Tff7b72= Tff7b72trueTb4b4b4,
Tb4b4b4)Tb4b4b4,
Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Tb4b4b4} Tff7b72else Tb4b4b4{
T8b949e// Send request to remote
Te6edf3packetHandlerTb4b4b4.Te6edf3sendToRadioTb4b4b4(
Te6edf3buildMeshPacketTb4b4b4(
Te6edf3to Tff7b72= Te6edf3destNumTb4b4b4,
Te6edf3wantAck Tff7b72= Tff7b72trueTb4b4b4,
Te6edf3id Tff7b72= Te6edf3requestIdTb4b4b4,
Te6edf3channel Tff7b72= Te6edf3getChannelIndexTb4b4b4(Te6edf3destNumTb4b4b4)Tb4b4b4,
Te6edf3decoded Tff7b72= Te6edf3DataTb4b4b4(Te6edf3portnum Tff7b72= Te6edf3PortNumTb4b4b4.Te6edf3NEIGHBORINFO_APPTb4b4b4, Te6edf3want_response Tff7b72= Tff7b72trueTb4b4b4, Te6edf3dest Tff7b72= Te6edf3destNumTb4b4b4)Tb4b4b4,
Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Tb4b4b4}
Tb4b4b4}
Tff7b72override Tff7b72fun Td2a8ffsendLockdownPassphraseTb4b4b4(
Te6edf3passphraseTb4b4b4: Tffa657StringTb4b4b4,
Te6edf3bootsTb4b4b4: Tffa657IntTb4b4b4,
Te6edf3hoursTb4b4b4: Tffa657IntTb4b4b4,
Te6edf3maxSessionSecondsTb4b4b4: Tffa657IntTb4b4b4,
Te6edf3disableTb4b4b4: Tffa657BooleanTb4b4b4,
Tb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3validUntilEpoch Tff7b72=
Tff7b72if Tb4b4b4(Te6edf3hours Tff7b72> T79c0ff0Tb4b4b4) Tb4b4b4{
Tb4b4b4(Te6edf3nowMillis Tff7b72/ Te6edf3MILLIS_PER_SECOND Tff7b72+ Te6edf3hoursTb4b4b4.Te6edf3toLongTb4b4b4(Tb4b4b4) Tff7b72* Te6edf3SECONDS_PER_HOURTb4b4b4)Tb4b4b4.Te6edf3toIntTb4b4b4(Tb4b4b4)
Tb4b4b4} Tff7b72else Tb4b4b4{
T79c0ff0
Tb4b4b4}
Tff7b72val Te6edf3lockdownAuth Tff7b72=
Te6edf3LockdownAuthTb4b4b4(
Te6edf3passphrase Tff7b72= Te6edf3passphraseTb4b4b4.Te6edf3encodeToByteArrayTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toByteStringTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3boots_remaining Tff7b72= Te6edf3bootsTb4b4b4.Te6edf3coerceAtLeastTb4b4b4(T79c0ff0Tb4b4b4)Tb4b4b4,
Te6edf3valid_until_epoch Tff7b72= Te6edf3validUntilEpochTb4b4b4,
Te6edf3max_session_seconds Tff7b72= Te6edf3maxSessionSecondsTb4b4b4.Te6edf3coerceAtLeastTb4b4b4(T79c0ff0Tb4b4b4)Tb4b4b4,
Te6edf3disable Tff7b72= Te6edf3disableTb4b4b4,
Tb4b4b4)
Te6edf3sendLockdownAdminTb4b4b4(Te6edf3AdminMessageTb4b4b4(Te6edf3lockdown_auth Tff7b72= Te6edf3lockdownAuthTb4b4b4)Tb4b4b4)
Tb4b4b4}
Tff7b72override Tff7b72fun Td2a8ffsendLockNowTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3sendLockdownAdminTb4b4b4(Te6edf3AdminMessageTb4b4b4(Te6edf3lockdown_auth Tff7b72= Te6edf3LockdownAuthTb4b4b4(Te6edf3lock_now Tff7b72= Tff7b72trueTb4b4b4)Tb4b4b4)Tb4b4b4)
Tb4b4b4}
Tff7b72private Tff7b72fun Td2a8ffsendLockdownAdminTb4b4b4(Te6edf3adminMessageTb4b4b4: Te6edf3AdminMessageTb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3myNum Tff7b72= Te6edf3nodeManagerTb4b4b4.Te6edf3myNodeNumTb4b4b4.Te6edf3value Tff7b72?: Tff7b72return
Tff7b72val Te6edf3packet Tff7b72=
Te6edf3MeshPacketTb4b4b4(
Te6edf3to Tff7b72= Te6edf3myNumTb4b4b4,
Te6edf3id Tff7b72= Te6edf3generatePacketIdTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3channel Tff7b72= T79c0ff0Tb4b4b4,
Te6edf3want_ack Tff7b72= Tff7b72trueTb4b4b4,
Te6edf3hop_limit Tff7b72= Te6edf3DEFAULT_HOP_LIMITTb4b4b4,
Te6edf3hop_start Tff7b72= Te6edf3DEFAULT_HOP_LIMITTb4b4b4,
Te6edf3priority Tff7b72= Te6edf3MeshPacketTb4b4b4.Te6edf3PriorityTb4b4b4.Te6edf3RELIABLETb4b4b4,
Te6edf3decoded Tff7b72= Te6edf3DataTb4b4b4(Te6edf3portnum Tff7b72= Te6edf3PortNumTb4b4b4.Te6edf3ADMIN_APPTb4b4b4, Te6edf3payload Tff7b72= Te6edf3adminMessageTb4b4b4.Te6edf3encodeTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toByteStringTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Te6edf3packetHandlerTb4b4b4.Te6edf3sendToRadioTb4b4b4(Te6edf3ToRadioTb4b4b4(Te6edf3packet Tff7b72= Te6edf3packetTb4b4b4)Tb4b4b4)
Tb4b4b4}
Tff7b72fun Td2a8ffresolveNodeNumTb4b4b4(Te6edf3addressTb4b4b4: Te6edf3NodeAddressTb4b4b4)Tb4b4b4: Tffa657Int Tff7b72= Tff7b72when Tb4b4b4(Te6edf3addressTb4b4b4) Tb4b4b4{
Te6edf3NodeAddressTb4b4b4.Te6edf3Broadcast Tff7b72-Tff7b72> Te6edf3NodeAddressTb4b4b4.Te6edf3NODENUM_BROADCAST
Te6edf3NodeAddressTb4b4b4.Te6edf3Local Tff7b72-Tff7b72> Te6edf3nodeManagerTb4b4b4.Te6edf3myNodeNumTb4b4b4.Te6edf3value Tff7b72?: T79c0ff0
Tff7b72is Te6edf3NodeAddressTb4b4b4.Te6edf3ByNum Tff7b72-Tff7b72> Te6edf3addressTb4b4b4.Te6edf3num
Tff7b72is Te6edf3NodeAddressTb4b4b4.Te6edf3ById Tff7b72-Tff7b72>
Te6edf3nodeManagerTb4b4b4.Te6edf3getNodeByIdTb4b4b4(Te6edf3addressTb4b4b4.Te6edf3idTb4b4b4)Tff7b72?.Te6edf3num
Tff7b72?: Tff7b72throw Te6edf3IllegalArgumentExceptionTb4b4b4(Ta5d6ff"Ta5d6ffUnknown node ID Tffd700${Te6edf3addressTb4b4b4.Te6edf3idTffd700}Ta5d6ff"Tb4b4b4)
Tb4b4b4}
Tff7b72private Tff7b72fun Td2a8ffbuildMeshPacketTb4b4b4(
Te6edf3toTb4b4b4: Tffa657IntTb4b4b4,
Te6edf3wantAckTb4b4b4: Tffa657Boolean Tff7b72= Tff7b72falseTb4b4b4,
Te6edf3idTb4b4b4: Tffa657Int Tff7b72= Te6edf3generatePacketIdTb4b4b4(Tb4b4b4)Tb4b4b4, T8b949e// always assign a packet ID if we didn't already have one
Te6edf3hopLimitTb4b4b4: Tffa657Int Tff7b72= T79c0ff0Tb4b4b4,
Te6edf3channelTb4b4b4: Tffa657Int Tff7b72= T79c0ff0Tb4b4b4,
Te6edf3priorityTb4b4b4: Te6edf3MeshPacketTb4b4b4.Te6edf3Priority Tff7b72= Te6edf3MeshPacketTb4b4b4.Te6edf3PriorityTb4b4b4.Te6edf3UNSETTb4b4b4,
Te6edf3decodedTb4b4b4: Te6edf3DataTb4b4b4,
Tb4b4b4)Tb4b4b4: Te6edf3MeshPacket Tb4b4b4{
Tff7b72val Te6edf3actualHopLimit Tff7b72= Tff7b72if Tb4b4b4(Te6edf3hopLimit Tff7b72> T79c0ff0Tb4b4b4) Te6edf3hopLimit Tff7b72else Te6edf3computeHopLimitTb4b4b4(Tb4b4b4)
Tff7b72var Te6edf3pkiEncrypted Tff7b72= Tff7b72false
Tff7b72var Te6edf3publicKeyTb4b4b4: Te6edf3ByteString Tff7b72= Te6edf3ByteStringTb4b4b4.Te6edf3EMPTY
Tff7b72var Te6edf3actualChannel Tff7b72= Te6edf3channel
Tff7b72if Tb4b4b4(Te6edf3channel Tff7b72=Tff7b72= Te6edf3NodeAddressTb4b4b4.Te6edf3PKC_CHANNEL_INDEXTb4b4b4) Tb4b4b4{
Te6edf3pkiEncrypted Tff7b72= Tff7b72true
Tff7b72val Te6edf3destNode Tff7b72= Te6edf3nodeManagerTb4b4b4.Te6edf3nodeDBbyNodeNumTff7b72[Te6edf3toTff7b72]
T8b949e// Resolve the public key using the same fallback as Node.hasPKC:
T8b949e// standalone publicKey (populated after Room round-trip) first, then
T8b949e// the embedded user.public_key (always available in-memory).
Te6edf3publicKey Tff7b72= Te6edf3destNodeTff7b72?.Te6edf3let Tb4b4b4{ Tffa657itTb4b4b4.Te6edf3publicKey Tff7b72?: Tffa657itTb4b4b4.Te6edf3userTb4b4b4.Te6edf3public_key Tb4b4b4} Tff7b72?: Te6edf3ByteStringTb4b4b4.Te6edf3EMPTY
Tff7b72if Tb4b4b4(Te6edf3publicKeyTb4b4b4.Te6edf3size Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3LoggerTb4b4b4.Te6edf3w Tb4b4b4{ Ta5d6ff"Ta5d6ffbuildMeshPacket: no public key for node Tffd700${Te6edf3toTb4b4b4.Te6edf3toUIntTb4b4b4(Tb4b4b4)Tffd700}Ta5d6ff, PKI encryption will failTa5d6ff" Tb4b4b4}
Tb4b4b4}
Te6edf3actualChannel Tff7b72= T79c0ff0
Tb4b4b4}
Tff7b72return Te6edf3MeshPacketTb4b4b4(
Te6edf3from Tff7b72= Te6edf3nodeManagerTb4b4b4.Te6edf3myNodeNumTb4b4b4.Te6edf3value Tff7b72?: T79c0ff0Tb4b4b4,
Te6edf3to Tff7b72= Te6edf3toTb4b4b4,
Te6edf3id Tff7b72= Te6edf3idTb4b4b4,
Te6edf3want_ack Tff7b72= Te6edf3wantAckTb4b4b4,
Te6edf3hop_limit Tff7b72= Te6edf3actualHopLimitTb4b4b4,
Te6edf3hop_start Tff7b72= Te6edf3actualHopLimitTb4b4b4,
Te6edf3priority Tff7b72= Te6edf3priorityTb4b4b4,
Te6edf3pki_encrypted Tff7b72= Te6edf3pkiEncryptedTb4b4b4,
Te6edf3public_key Tff7b72= Te6edf3publicKeyTb4b4b4,
Te6edf3channel Tff7b72= Te6edf3actualChannelTb4b4b4,
Te6edf3decoded Tff7b72= Te6edf3decodedTb4b4b4,
Tb4b4b4)
Tb4b4b4}
Tff7b72private Tff7b72fun Td2a8ffbuildAdminPacketTb4b4b4(
Te6edf3toTb4b4b4: Tffa657IntTb4b4b4,
Te6edf3idTb4b4b4: Tffa657Int Tff7b72= Te6edf3generatePacketIdTb4b4b4(Tb4b4b4)Tb4b4b4, T8b949e// always assign a packet ID if we didn't already have one
Te6edf3wantResponseTb4b4b4: Tffa657Boolean Tff7b72= Tff7b72falseTb4b4b4,
Te6edf3adminMessageTb4b4b4: Te6edf3AdminMessageTb4b4b4,
Tb4b4b4)Tb4b4b4: Te6edf3MeshPacket Tff7b72=
Te6edf3buildMeshPacketTb4b4b4(
Te6edf3to Tff7b72= Te6edf3toTb4b4b4,
Te6edf3id Tff7b72= Te6edf3idTb4b4b4,
Te6edf3wantAck Tff7b72= Tff7b72trueTb4b4b4,
Te6edf3channel Tff7b72= Te6edf3getAdminChannelIndexTb4b4b4(Te6edf3toTb4b4b4)Tb4b4b4,
Te6edf3priority Tff7b72= Te6edf3MeshPacketTb4b4b4.Te6edf3PriorityTb4b4b4.Te6edf3RELIABLETb4b4b4,
Te6edf3decoded Tff7b72=
Te6edf3DataTb4b4b4(
Te6edf3want_response Tff7b72= Te6edf3wantResponseTb4b4b4,
Te6edf3portnum Tff7b72= Te6edf3PortNumTb4b4b4.Te6edf3ADMIN_APPTb4b4b4,
Te6edf3payload Tff7b72= Te6edf3adminMessageTb4b4b4.Te6edf3encodeTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toByteStringTb4b4b4(Tb4b4b4)Tb4b4b4,
Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Tff7b72companion Tff7b72object Tb4b4b4{
Tff7b72private Tff7b72const Tff7b72val Te6edf3PACKET_ID_MASK Tff7b72= T79c0ff0Te6edf3xffffffffL
Tff7b72private Tff7b72const Tff7b72val Te6edf3PACKET_ID_SHIFT_BITS Tff7b72= T79c0ff3T79c0ff2
Tff7b72private Tff7b72const Tff7b72val Te6edf3ADMIN_CHANNEL_NAME Tff7b72= Ta5d6ff"Ta5d6ffadminTa5d6ff"
Tff7b72private Tff7b72const Tff7b72val Te6edf3DEFAULT_HOP_LIMIT Tff7b72= T79c0ff3
Tff7b72private Tff7b72const Tff7b72val Te6edf3MILLIS_PER_SECOND Tff7b72= T79c0ff1T79c0ff0T79c0ff0T79c0ff0L
Tff7b72private Tff7b72const Tff7b72val Te6edf3SECONDS_PER_HOUR Tff7b72= T79c0ff3T79c0ff6T79c0ff0T79c0ff0
Tb4b4b4}
Tb4b4b4}
Served by rngit 1.5.0 - Generated in 0.12s